import random
import math

from django.db import models

class damageType(models.Model):
    #damage types for the damage class
    name = models.CharField(max_length = 20, unique = True)
    physical = models.BooleanField()
    
    def __unicode__(self):
        return self.name
        
    @property
    def isPhysical(self):
        return self.physical
        
    @property
    def isMagical(self):
        return not self.physical
        
class damage(models.Model):
    #Damage generated by an attack
    damageType=models.ForeignKey('damage.damageType', default = 1)
    amount=models.PositiveIntegerField(default=0) #damage to be dealt
    power=models.IntegerField(default=0)          #Compared to defence power, adds/reduces damage amount
        
    def addDamage(self, amount):
        """increases the damage by the amount given """
        if type(amount) not in (int,long):
            return
        self.amount += amount
        if self.amount < 0:
            self.amount = 0
            
    def applyDamage(self, monster):
        """calculates resistances and deals out final damage to target"""
        defence = monster.getDefence(self.damageType)
        diff =self.power - defence
        #5% damage bonus per difference in power
        multiplier = (100 + diff*5)/100
        totalDamage = math.ceil(self.amount * multiplier)
        damageDealt = monster.addDamage(totalDamage)
        return damageDealt
        
class damageModifier(models.Model):
    """Adds damage amount for a damageType for either attack and defence"""
    damageType = models.ForeignKey('damage.damageType')
    damageModifierCollection = models.ForeignKey('damage.damageModifierCollection')
    power = models.IntegerField(default=1)
    defence = models.BooleanField(default=1)  #1 modifies defence, 0 modifies attack
    

class damageModifierCollection(models.Model):
    #Belongs to an individual object that modifies damage
    basePhysicalDefence = models.IntegerField(default = 0)
    baseMagicalDefence  = models.IntegerField(default = 0)
    basePhysicalAttack  = models.IntegerField(default = 0)
    baseMagicalAttack   = models.IntegerField(default = 0)
    modifiers =  models.ManyToManyField(damageType,
                 through = damageModifier,null=True)
    description = models.CharField(max_length=50, null=True)
    
    def __unicode__(self):
        return self.description
        
    def getDefence(self, dt):
        """ Returns the defence power for a given damageType """
        dm = self.damagemodifier_set.filter(damageType = dt, defence=1)
        
        if dm:
            power=0
            for x in dm:    #return total resistance for all types
                power +=x.power
            return power
            
        elif dt.isPhysical:     #no reistance to this type, use base
            return self.basePhysicalDefence
        return self.baseMagicalDefence
        
    def getAttack(self, dt):
        """ Returns the attack bonus for a given damageType """
        dm = self.damagemodifier_set.filter(damageType = dt, defence=0)
        
        if dm:
            power = 0
            for x in dm:
                power +=x.power
            return power
            
        elif dt.isPhysical:
            return self.basePhysicalAttack
            
        return self.baseMagicalAttack
